package com.zhanghp.class039;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * 含有嵌套的分子式求原子数量 - 打印字母<br/>
 * <p>
 *     此题，是在code03，我看错生成输出后，自己写的，喵的，不过也变相练了一下左神的嵌套公式<br/>
 *     不过数据结构可以优化，因为我后面喵了一眼左神解法，用的map<br/>
 * </p>
 * <p>
 *     <ul>示例1
 *     <li>
 *         K4(ON(SO3)2)2
 *     </li>
 *     <li>
 *         KKKKONSOOOSOOOONSOOOSOOO
 *     </li>
 *     </ul>
 *     <ul>示例2
 *     <li>
 *          K4(SO3)2
 *     </li>
 *     <li>
 *         KKKKSOOOSOOO
 *     </li>
 *     </ul>
 * </p>
 *<br/>
 * <hr/>
 * <h1>适用于1个大写字母的原子，并且重复数字小于10</h1>
 * @author zhanghp
 * @since 2024/6/21 16:28
 */
public class Code03_NumberOfAtoms_Extension {

    /**
     * 校验用的，因为自己写跑题了，也没个leetcode，nnd
     *
     * @param s
     */
    public static void validCount(String s){
        Map<Character, Integer> map = new HashMap<>();
        for (char c : s.toCharArray()) {
            if (map.containsKey(c)) {
                map.put(c, map.get(c) + 1);
            }else {
                map.put(c, 1);
            }
        }
        map.forEach((k,v) -> {
            System.out.print(k + ":" + v + ",");
        });
        System.out.println();
    }

    public static void main(String[] args) {
        String s = new Code03_NumberOfAtoms_Extension().countOfAtoms("K4(ON(SO3)2)2");
        System.out.println(s);
        validCount(s);
        String s2 = new Code03_NumberOfAtoms_Extension().countOfAtoms("K4(SO3)2");
        System.out.println(s2);
        validCount(s2);
    }

    // =====================================解题==================================================


    public String countOfAtoms(String formula) {
        where = 0;
        return f(formula.toCharArray(), 0);
    }


    public static int where;

    public static String f(char[] c, int index) {
        ArrayList<Character> list = new ArrayList<>();
        // 记录嵌套时括号后的一位索引，用来数字，重复打印
        int nestRepeatIndex = 0;
        int repeat = 0;
        while (index < c.length && c[index] != ')') {
            if ((c[index] >= 'a' && c[index] <= 'z') || (c[index] >= 'A' && c[index] <= 'Z')) {
                // 原子后面如果没数字，则默认为1，所以怎么的都得打印，所以我提前塞进去了
                list.add(c[index++]);
            } else if (c[index] == '(') {
                nestRepeatIndex = list.size();
                stringAddList(list, f(c, index + 1));
                index = where + 1;
            } else {
                repeat = repeat * 10 + (c[index ++] - '0');
                if (nestRepeatIndex != 0) {
                    stringAddList(list, get(list, nestRepeatIndex));
                }else {
                    // 每回字母都会加进去，所以repeat-1
                    repeat(list, repeat - 1);
                }
                repeat = nestRepeatIndex = 0;
            }
        }
        where = index;
        return get(list, 0);
    }

    public static String get(ArrayList<Character> list, int start) {
        StringBuilder sb = new StringBuilder();
        for (int i = start; i < list.size(); i++) {
            sb.append(list.get(i));

        }
        return sb.toString();
    }

    public static void stringAddList(ArrayList<Character> list, String str) {
        for (char c : str.toCharArray()) {
            list.add(c);
        }
    }

    public static void repeat(ArrayList<Character> list , int repeat){
        Character c = list.get(list.size() - 1);
        for (int i = 0; i < repeat; i++) {
            list.add(c);
        }
    }

}
